<script setup>
import { ref, reactive, watch, onMounted, onBeforeUnmount, nextTick } from 'vue';
import { sensorByIdData, sensorByIdDvalue, sensorByIdDiff } from '@T2/service/api.ts';
import vueECharts from "vue-echarts";
import dayjs from 'dayjs';
const props = defineProps({
  realBox: {
    type: Object,
    required: true,
  },
  position: {
    type: Array,
    required: true,
  },
  label: {
    type: Object,
    required: true,
  },
  option: {
    type: Object,
    required: true,
  },
  params: {
    type: Array,
    required: true,
  },
});

const chartRef = ref(null);
let timer = null;
onMounted(() => {
  beforeGetData();
  timer = setInterval(() => {
    beforeGetData();
  }, 10000);
});
onBeforeUnmount(() => {
  if (timer) {
    clearInterval(timer);
  }
});
let yMax = 0, unitCg = 'first', seriesInfo = [];
const beforeGetData = () => {
  chartRef.value.chart.clear();
  props.option.dataset = [];
  props.option.series = [];
  yMax = 0;
  unitCg = 'first';
  seriesInfo = [];
  props.params.forEach((params, index) => {
    if (params.t === "c") {
      getCurLine(params);
    } else if (params.t === "ch") {
      getHourLine(params);
    } else if (params.t === "cd") {
      getDayLine(params);
    } else if (params.t === "cm") {
      getMonthLine(params);
    }
  });
}
const getCurLine = (params) => {
  params.s && sensorByIdData({
    method: "get",
    id: params.s,
    params: {
      page: 1,
      pagesize: 1000,
      ordering: '-create_time',
      start: dayjs().format('YYYY-MM-DD') + " 00:00:00",
      end: dayjs().format('YYYY-MM-DD') + " 23:59:59",
    },
  }).then((res) => {
    let { results, unit, map } = res;
    if (map) {
      let source = [];
      let mapNew = {};
      for (let key in map) {
        let value = map[key];
        if (value) {
          [value, key] = [key, value];
          mapNew[key] = +value;
        }
      }
      let stepH = Object.keys(mapNew).length;
      seriesInfo.push({
        stepH: stepH,
      });
      results.forEach(item => {
        item.data = item.data;
        source.push([item.create_time, item.data, mapNew[item.data], mapNew[item.data]]);
      });
      props.option.dataset.push({
        dimensions: ['time', 'data', 'mapData', 'tarData'],
        source,
      });
      const len = props.option.dataset.length - 1;
      props.option.series.push({
        name: params.n,
        type: "line",
        showSymbol: false,
        lineStyle: {
          width: 1,
        },
        itemStyle: {
          color: params.o,
        },
        datasetIndex: len,
        encode: { x: 'time', y: 'tarData' },
        step: 'end',
      });
    } else {
      let source = [];
      results.forEach(item => {
        item.data = +item.data;
        if (item.data > yMax) {
          yMax = item.data;
        }
        source.push([item.create_time, item.data, (item.data / 10000).toFixed(2)]);
      });
      props.option.dataset.push({
        dimensions: ['time', 'data', 'miniData'],
        source,
      });
      seriesInfo.push({
        unit: unit,
        oriUnit: unit,
      });
      const len = props.option.dataset.length - 1;
      props.option.series.push({
        name: params.n,
        type: "line",
        showSymbol: false,
        lineStyle: {
          width: 1,
        },
        itemStyle: {
          color: params.o,
        },
        datasetIndex: len,
      });
      encodeCheck(unit, params);
    }
    if (unitCg !== 'first') {
      let ym = 0;
      if (unitCg === 'error' || yMax <= 10000) {
        ym = yMax;
      } else {
        ym = yMax / 10000;
      }
      props.option.series.forEach((i, dex) => {
        if (i.step) {
          const mulp = getMulPower(seriesInfo[dex].stepH, ym);
          const sub = props.option.dataset[dex].dimensions.indexOf(i.encode.y);
          const _sub = props.option.dataset[dex].dimensions.indexOf('mapData');
          props.option.dataset[dex].source.forEach(j => {
            j[sub] = j[_sub] * mulp;
          });
        }
      });
    }
    props.option.xAxis.min = dayjs().format('YYYY-MM-DD') + " 00:00:00";
    props.option.xAxis.max = dayjs().format('YYYY-MM-DD') + " 23:59:59";
    const splitNumber = (props.label.width / 100 / props.realBox.scale).toFixed(0);
    props.option.xAxis.splitNumber = splitNumber <= 1 ? 2 : splitNumber;
    props.option.xAxis.axisLabel.formatter = function (value) {
      return dayjs(value).format('HH:mm');
    };
    props.option.tooltip.formatter = function(par) {
      let time = par.length && dayjs(par[0].data[0]).format("YYYY-MM-DD HH:mm:ss");
      let res = time + '<br/>';
      par.forEach((ser, ind) => {
        let value = '', ut = '';
        if (props.option.series[ser.seriesIndex].step) {
          const _sub = ser.dimensionNames.indexOf('data');
          value = ser.data[_sub];
        } else if (seriesInfo.length > ser.seriesIndex) {
          value = ser.data[ser.encode.y] + '&nbsp;';
          ut = seriesInfo[ser.seriesIndex].unit;
        }
        res = res
          + `<div style="display:flex;align-items:center;justify-content:space-between;margin-top:4px;">`
            + `<div style="display:flex;align-items:center;font-size:${props.option.tooltip.textStyle.fontSize}px">`
              + ser.marker
              + ser.seriesName
            + '</div>'
            + `<div style="display:flex;align-items:center;margin-left:15px;font-size:${props.option.tooltip.textStyle.fontSize}px">`
              + `<b style="font-size:${props.option.tooltip.textStyle.fontSize * 1.5}px">${value}</b>`
              + ut
            + '</div>'
          + '</div>'
      });
      return res;
    };
    chartRef.value.chart.setOption(props.option, false);
  })
}

const getHourLine = (params) => {
  params.s && sensorByIdDvalue({
    method: "get",
    id: params.s,
    params: {
      status: "每小时",
      ordering: '-create_time',
      start: dayjs().format('YYYY-MM-DD') + " 01:00:00",
      end: dayjs(dayjs().format('YYYY-MM-DD')).add(1, 'day').format("YYYY-MM-DD") + " 00:01:00",
    },
  }).then(res => {
    let { results, unit, } = res;
    let source = [];
    results.forEach(item => {
      item.data = +item.data;
      if (item.data > yMax) {
        yMax = item.data;
      }
      source.push([
        dayjs(item.create_time).subtract(1, 'hour').format("YYYY-MM-DD HH") + ":00:00",
        item.data,
        (item.data / 10000).toFixed(2),
      ]);
    });
    dValueCommon(source, unit, params);
    props.option.xAxis.min = dayjs().format('YYYY-MM-DD') + " 00:00:00";
    props.option.xAxis.max = dayjs().format('YYYY-MM-DD') + " 23:59:59";
    const splitNumber = (props.label.width / 100 / props.realBox.scale).toFixed(0);
    props.option.xAxis.splitNumber = splitNumber <= 1 ? 2 : splitNumber;
    props.option.xAxis.axisLabel.formatter = function (value) {
      return dayjs(value).format('HH时');
    };
    props.option.tooltip.formatter = function(par) {
      let time = par.length && dayjs(par[0].data[0]).format("YYYY-MM-DD HH时");
      let res = time + '<br/>';
      par.forEach(ser => {
        let ut = '';
        if (seriesInfo.length > ser.seriesIndex) {
          ut = seriesInfo[ser.seriesIndex].unit;
        }
        res = res
          + `<div style="display:flex;align-items:center;justify-content:space-between;margin-top:4px;">`
            + `<div style="display:flex;align-items:center;font-size:${props.option.tooltip.textStyle.fontSize}px">`
              + ser.marker
              + ser.seriesName
            + '</div>'
            + `<div style="display:flex;align-items:center;margin-left:15px;font-size:${props.option.tooltip.textStyle.fontSize}px">`
              + `<b style="font-size:${props.option.tooltip.textStyle.fontSize * 1.5}px">${ser.data[ser.encode.y]}&nbsp;</b>`
              + ut
            + '</div>'
          + '</div>'
      });
      return res;
    };
    chartRef.value.chart.setOption(props.option, false);
  });
}

const getDayLine = (params) => {
  Promise.all([getDayDvalue(params), getIdDiff(params)]).then(res => {
    let { results, unit, } = res[0];
    let { today } = res[1];
    if (dayjs().format('YYYY-MM') === dayjs().format('YYYY-MM')) {
      results.push({
        id: null,
        create_time: dayjs().add(1, 'day').format("YYYY-MM-DD") + " 00:01:00",
        data: today,
      });
    }
    let source = [];
    results.forEach(item => {
      item.data = +item.data;
      if (item.data > yMax) {
        yMax = item.data;
      }
      source.push([
        dayjs(item.create_time).subtract(1, 'day').format("YYYY-MM-DD") + " 00:00:00",
        item.data,
        (item.data / 10000).toFixed(2),
      ]);
    });
    dValueCommon(source, unit, params);
    props.option.xAxis.min = dayjs().format('YYYY-MM') + "-01 00:00:00";
    props.option.xAxis.max = dayjs(dayjs().format('YYYY-MM')).add(1, 'month').subtract(1, 'day').format("YYYY-MM-DD") + " 01:00:00";
    const splitNumber = (props.label.width / 100 / props.realBox.scale).toFixed(0);
    props.option.xAxis.splitNumber = splitNumber <= 1 ? 2 : splitNumber;
    props.option.xAxis.axisLabel.formatter = function (value) {
      return dayjs(value).format('DD日');
    };
    props.option.tooltip.formatter = function(par) {
      let time = par.length && dayjs(par[0].data[0]).format("YYYY年MM月DD日");
      let res = time + '<br/>';
      par.forEach(ser => {
        let ut = '';
        if (seriesInfo.length > ser.seriesIndex) {
          ut = seriesInfo[ser.seriesIndex].unit;
        }
        res = res
          + `<div style="display:flex;align-items:center;justify-content:space-between;margin-top:4px;">`
            + `<div style="display:flex;align-items:center;font-size:${props.option.tooltip.textStyle.fontSize}px">`
              + ser.marker
              + ser.seriesName
            + '</div>'
            + `<div style="display:flex;align-items:center;margin-left:15px;font-size:${props.option.tooltip.textStyle.fontSize}px">`
              + `<b style="font-size:${props.option.tooltip.textStyle.fontSize * 1.5}px">${ser.data[ser.encode.y]}&nbsp;</b>`
              + ut
            + '</div>'
          + '</div>'
      });
      return res;
    };
    chartRef.value.chart.setOption(props.option, false);
  });
}

const getDayDvalue = (params) => {
  return new Promise((resolve, reject) => {
    params.s && sensorByIdDvalue({
      method: "get",
      id: params.s,
      params: {
        status: "每日",
        ordering: '-create_time',
        start: dayjs().format("YYYY-MM") + "-02 00:00:00",
        end: dayjs(dayjs().format('YYYY-MM')).add(1, 'month').format("YYYY-MM") + "-01 00:01:00",
      },
    }).then(res => {
      resolve(res);
    }).catch(e => {
      reject(e);
    });
  });
}

const getMonthLine = (params) => {
  Promise.all([getMonthDvalue(params), getIdDiff(params)]).then(res => {
    let { results, unit, } = res[0];
    let { month } = res[1];
    if (dayjs().format('YYYY') === dayjs().format('YYYY')) {
      results.push({
        id: null,
        create_time: dayjs().add(1, 'month').format("YYYY-MM") + "-01 00:01:00",
        data: month,
      });
    }
    let source = [];
    results.forEach(item => {
      item.data = +item.data;
      if (item.data > yMax) {
        yMax = item.data;
      }
      source.push([
        dayjs(item.create_time).subtract(1, 'month').format("YYYY-MM") + "-01 00:00:00",
        item.data,
        (item.data / 10000).toFixed(2),
      ]);
    });
    dValueCommon(source, unit, params);
    props.option.xAxis.min = dayjs().format('YYYY') + "-01-01 00:00:00";
    props.option.xAxis.max = dayjs(dayjs().format('YYYY')).add(1, 'year').subtract(1, 'month').format("YYYY-MM") + "-02 00:00:00";
    const splitNumber = (props.label.width / 100 / props.realBox.scale).toFixed(0);
    props.option.xAxis.splitNumber = splitNumber <= 1 ? 2 : splitNumber;
    props.option.xAxis.axisLabel.formatter = function (value) {
      return dayjs(value).format('MM月');
    };
    props.option.tooltip.formatter = function(par) {
      let time = par.length && dayjs(par[0].data[0]).format("YYYY年MM月");
      let res = time + '<br/>';
      par.forEach(ser => {
        let ut = '';
        if (seriesInfo.length > ser.seriesIndex) {
          ut = seriesInfo[ser.seriesIndex].unit;
        }
        res = res
          + `<div style="display:flex;align-items:center;justify-content:space-between;margin-top:4px;">`
            + `<div style="display:flex;align-items:center;font-size:${props.option.tooltip.textStyle.fontSize}px">`
              + ser.marker
              + ser.seriesName
            + '</div>'
            + `<div style="display:flex;align-items:center;margin-left:15px;font-size:${props.option.tooltip.textStyle.fontSize}px">`
              + `<b style="font-size:${props.option.tooltip.textStyle.fontSize * 1.5}px">${ser.data[ser.encode.y]}&nbsp;</b>`
              + ut
            + '</div>'
          + '</div>'
      });
      return res;
    };
    chartRef.value.chart.setOption(props.option, false);
  });
}

const getMonthDvalue = (params) => {
  return new Promise((resolve, reject) => {
    params.s && sensorByIdDvalue({
      method: "get",
      id: params.s,
      params: {
        status: "每月",
        ordering: '-create_time',
        start: dayjs().format("YYYY") + "-02-01 00:00:00",
        end: dayjs(dayjs().format('YYYY')).add(1, 'year').format("YYYY") + "-02-01 00:01:00",
      },
    }).then(res => {
      resolve(res);
    }).catch(e => {
      reject(e);
    });
  });
}

const getIdDiff = (params) => {
  return new Promise((resolve, reject) => {
    params.s && sensorByIdDiff({
      method: "get",
      id: params.s,
      params: {},
    }).then(res => {
      resolve(res);
    }).catch(e => {
      reject(e);
    });
  });
}

const getMulPower = (len = 1, max = 0) => {
  if (len === 0) {
    return 1;
  } else {
    const consult = max / (len - 1) / 2;
    const exp = consult.toExponential().split('e');
    const x = +exp[0];
    const y = +exp[1];
    return +(x * 10 ** y).toFixed(1);
  }
}

const dValueCommon = (source, unit, params) => {
  props.option.dataset.push({
    dimensions: ['time', 'data', 'miniData'],
    source,
  });
  seriesInfo.push({
    unit: unit,
    oriUnit: unit,
  });
  const len = props.option.dataset.length - 1;
  props.option.series.push({
    name: params.n,
    type: "line",
    showSymbol: true,       //不加这个会导致多系列时，只有一个系列显示了标记
    symbolSize: 4 * props.realBox.scale,
    lineStyle: {
      width: 1,
    },
    itemStyle: {
      color: params.o,
    },
    datasetIndex: len,
  });
  encodeCheck(unit, params);
}

const encodeCheck = (unit, params) => {
  if (unitCg === 'first' || unitCg === unit) {
    if (unitCg === 'first') {
      unitCg = unit;
    }
    if (yMax > 10000) {
      props.option.yAxis.name = '万' + unit;
      props.option.series.forEach(i => {
        if (!i.step) {
          i.encode = { x: 'time', y: 'miniData' }
        }
      });
      seriesInfo.forEach(i => {
        if (!i.step) {
          i.unit = '万' + i.oriUnit;
        }
      });
    } else {
      props.option.yAxis.name = unit;
      props.option.series.forEach(i => {
        if (!i.step) {
          i.encode = { x: 'time', y: 'data' }
        }
      });
    }
  } else {
    unitCg = 'error';
    props.option.yAxis.name = '';
    props.option.series.forEach(i => {
      if (!i.step) {
        i.encode = { x: 'time', y: 'data' }
      }
    });
  }
}


</script>

<template>
  <div
    class="floatItem"
    :style="{
      left: props.position[0] * props.realBox.scale + 'px',
      top: props.realBox.height - props.position[1] * props.realBox.scale + 'px',
      transform: `translate(-50%, -50%) rotate(${- props.label.rotate}deg)`,
      width: props.label.width + 'px',
      height: props.label.height + 'px',
      border: `${props.label.borderWidth}px solid ${props.label.borderColor}`,
      opacity: props.label.opacity_temp,
      backgroundColor: props.label.backgroundColor,
      boxShadow: `inset 0 0 20px ${props.label.shadow}`,
    }"
  >
    <vueECharts ref="chartRef" autoresize :option="props.option" />
  </div>
</template>

<style lang="scss" scoped>
.floatItem {
  position: absolute;
  left: 20px;
  display: flex;
}
</style>